/**
 * @description works and template service
 */

const _ = require('lodash')
const WorksModel = require('../model/work')
const { formatDate } = require('../utils/util')
const { DEFAULT_PAGE_SIZE } = require('../config/constant')

const defaultPageCondition = {
  pageIndex: 0,
  pageSize: DEFAULT_PAGE_SIZE
}

/**
 * 查询 作品/模板 列表
 * @param {object} whereOpt 查询条件
 * @param {object} pageOpt 分页数据
 */
async function findWorkList(whereOpt = {}, pageOpt = {}) {
  const select =
    'id uuid author copiedCount coverImg desc title user isTemplate isHot isPublic createdAt latestPublishAt status orderIndex'
  const populate = { path: 'user', select: 'username nickName picture' }
  const pageCondition = { ...defaultPageCondition, ...pageOpt }
  const { pageSize, pageIndex } = pageCondition
  const skip = pageIndex * pageSize

  const result = await WorksModel.find(whereOpt)
    .select(select) // 查询的字段
    .populate(populate) // 查询作品记录  populate 关联哪些集合以及返回哪些值
    .skip(skip) // 跳过多少条
    .limit(pageSize) // 每页多少条
    .sort({ orderIndex: -1, id: -1 }) // 倒序
  // .lean() // 直接返回 object 对象，不需要返回 Document 类型的对象，加快查询速度

  const count = await WorksModel.find(whereOpt).count()

  return {
    count,
    list: result,
    pageSize,
    pageIndex
  }
}

/**
 * 更新单个作品数据
 * @param {object} updateData 要更新的数据
 * @param {object} whereOpt 查询提交件
 * @returns {Promise<boolean>} true/false
 */
async function updateWork(updateData = {}, whereOpt = {}) {
  // 保证数据不为空
  if (_.isEmpty(updateData)) return false
  if (_.isEmpty(whereOpt)) return false

  const result = await WorksModel.findOneAndUpdate(whereOpt, updateData, { new: true })
  return !!result
}

/**
 * 批量更新作品数据
 * @param {object} updateData 要更新的数据
 * @param {object} whereOpt 查询提交件
 * @returns {Promise<boolean>} true/false
 */
async function updateWorks(updateData = {}, whereOpt = {}) {
  // 保证数据不为空
  if (_.isEmpty(updateData)) return false
  if (_.isEmpty(whereOpt)) return false
  // const result = await WorksModel.updateMany({ id: { $in: [1, 2] }, isTemplate: true }, { $set: { isPublic: true } })
  const result = await WorksModel.updateMany(whereOpt, updateData)
  console.log('updateWorks', result)
  return result.modifiedCount !== 0
}

/**
 * 获取总数
 * @param {object} whereOpt 条件
 */
async function getWorksCount(whereOpt = {}) {
  const result = await WorksModel.count(whereOpt)
  return result
}

/**
 * 按月，统计创建数量
 * @param {Date} startTime 开始时间 世界标准时区 和我们相差8个小时
 * @param {Date} endTime 结束时间
 */
async function getCreatedCountMonthly(startTime, endTime) {
  const result = await WorksModel.aggregate([
    { $match: { createdAt: { $gte: startTime, $lte: endTime } } }, // createdAt >= startTime and createdAt <= endTime
    { $project: { month: { $dateToString: { format: '%Y-%m', date: '$createdAt', timezone: '+08:00' } } } }, // 世界标准时间和我们时差相差8，我们是+8时区，所以+8小时就是系统当前时间
    { $group: { _id: '$month', count: { $sum: 1 } } },
    { $sort: { _id: 1 } }
  ]).exec()
  return result
}

/**
 * 按月，统计发布数量
 * @param {Date} startTime 开始时间 世界标准时区 和我们相差8个小时
 * @param {Date} endTime 结束时间
 */
async function getPublishedCountMonthly(startTime, endTime) {
  const result = await WorksModel.aggregate([
    { $match: { status: 2, latestPublishAt: { $gte: startTime, $lte: endTime } } },
    { $project: { month: { $dateToString: { format: '%Y-%m', date: '$latestPublishAt', timezone: '+08:00' } } } }, // 世界标准时间和我们时差相差8，我们是+8时区，所以+8小时就是系统当前时间
    { $group: { _id: '$month', count: { $sum: 1 } } },
    { $sort: { _id: 1 } }
  ]).exec()
  return result
}

module.exports = {
  findWorkList,
  updateWork,
  updateWorks,
  getWorksCount,
  getCreatedCountMonthly,
  getPublishedCountMonthly
}
